package cn.kmsoft.stgeometry.util;

import cn.kmsoft.wololo.object.GeoJson;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import org.geotools.data.FeatureSource;
import org.geotools.data.shapefile.ShapefileDataStore;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.geojson.feature.FeatureJSON;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.geometry.BoundingBox;

import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Map;

public class Shapefile2GeoJson {
    /**
     * @param args
     */
    public static void main(String[] args) {
        // counties();
        // shelter();
        String shppath = "D:\\temp\\新建文件夹\\layer_2080427802Copy.shp";
        String jsonpath = "D:\\temp\\新建文件夹\\layer_2080427802Copy.json";

        //shp2GeoJson(shppath,jsonpath);
        //shp2GeoJson2(shppath);
        shp2GeoJson3(shppath);
    }

    private static void counties() {
        String path = "file:///D:\\temp\\layer_2080427802.shp";
        ShapefileDataStore datastore = null;

        try {
            URL url = new URL(path);
            datastore = new ShapefileDataStore(url);
            datastore.setCharset(Charset.forName("GBK"));
            String type = datastore.getTypeNames()[0];

            FeatureSource<SimpleFeatureType, SimpleFeature> source = null;
            source = (FeatureSource<SimpleFeatureType, SimpleFeature>) datastore
                    .getFeatureSource(type);
            FeatureCollection<SimpleFeatureType, SimpleFeature> collections = source
                    .getFeatures();
            FeatureIterator<SimpleFeature> iterator = collections.features();

            /*
             * "500101": { "name": "万州区", "extent": { "xmin": 0, "ymin": 0,
             * "xmax": 0, "ymax": 0, "spatialReference": { "wkid": 2332 } }
             */
            JSONObject counties = new JSONObject();
            JSONObject reference = new JSONObject();
            reference.put("wkid", 2332);

            while (iterator.hasNext()) {
                SimpleFeature feature = iterator.next();

                String code = (String) feature.getAttribute("XZQDM");
                String name = (String) feature.getAttribute("XZQMC");
                BoundingBox box = feature.getBounds();

                JSONObject extent = new JSONObject();
                extent.put("xmin", box.getMinX());
                extent.put("ymin", box.getMinY());
                extent.put("xmax", box.getMaxX());
                extent.put("ymax", box.getMaxY());
                extent.put("spatialReference", reference);
                JSONObject county = new JSONObject();
                county.put("name", name);
                county.put("extent", extent);

                counties.put(code, county);
            }

            System.out.println(counties);
            iterator.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private static void shelter() {
        String path = "file:///D:\\temp\\新建文件夹\\layer_2080427802Copy.shp";
        ShapefileDataStore datastore = null;

        try {
            URL url = new URL(path);
            datastore = new ShapefileDataStore(url);
            datastore.setCharset(Charset.forName("GBK"));
            String type = datastore.getTypeNames()[0];
            SimpleFeatureSource featureSource = datastore
                    .getFeatureSource(type);
            SimpleFeatureCollection collections = featureSource.getFeatures();
            SimpleFeatureIterator iterator = collections.features();

            /* "{uuid}": ["{code}"...] */
            JSONObject shelter = new JSONObject();

            FeatureJSON fjson = new FeatureJSON();
            while (iterator.hasNext()) {
                SimpleFeature feature = iterator.next();

                StringWriter writer = new StringWriter();
                fjson.writeFeature(feature, writer);
                String json = writer.toString();
            }
            iterator.close();

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public JSONObject getGeometry(String hh) {
        JSONObject j = new JSONObject();

        return j;
    }

    /**
     * Shp文件转换为GeoJson对象
     *
     * @param shppath  shp文件路径
     * @return
     */
    public static GeoJson shp2GeoJson(String shppath) {
        JSONObject geoJson = null;
        try {
            String charsetName = ShpUtil.getShpCharsetName(shppath);
            geoJson = ShpUtil.toGeoJson(shppath,charsetName);
        } catch (Exception e) {
            e.printStackTrace();
        }

        String geoJsonStr = "";
        if (geoJson != null) {
            geoJsonStr = JSON.toJSONString(geoJson);
        }
        GeoJson geojson = JSON.parseObject(geoJsonStr,GeoJson.class);
        return geojson;
    }


    public static GeoJson shp2GeoJson(String shppath,String encoding) {
        JSONObject geoJson = null;
        try {
            geoJson = ShpUtil.toGeoJson(shppath, encoding);
        } catch (Exception e) {
            e.printStackTrace();
        }

        String geoJsonStr = "";
        if (geoJson != null) {
            geoJsonStr = JSON.toJSONString(geoJson);
        }
        GeoJson geojson = JSON.parseObject(geoJsonStr,GeoJson.class);
        return geojson;
    }

    /**
     * Shp文件转换为GeoJson字符串
     *
     * @param shppath  shp文件路径
     * @return
     */
    public static String shp2GeoJsonStr(String shppath) {
        JSONObject geoJson = null;
        try {
            geoJson = ShpUtil.toGeoJson(shppath);
        } catch (Exception e) {
            e.printStackTrace();
        }

        String geoJsonStr = "";
        if (geoJson != null) {
            geoJsonStr = JSON.toJSONString(geoJson);
        }

        return geoJsonStr;
    }

    public static String shp2GeoJsonStr(String shppath, String encoding) {
        JSONObject geoJson = null;
        try {
            geoJson = ShpUtil.toGeoJson(shppath, encoding);
        } catch (Exception e) {
            e.printStackTrace();
        }

        String geoJsonStr = "";
        if (geoJson != null) {
            geoJsonStr = JSON.toJSONString(geoJson);
        }

        return geoJsonStr;
    }

    /**
     * Shp文件转换为GeoJson字符串，并保存到json文件中
     *
     * @param shapPath
     * @param jsonPath
     */
    public static void shp2GeoJsonFile(String shapPath, String jsonPath) {
        ShapefileDataStore datastore = null;
        FeatureJSON fjson = new FeatureJSON();

        try {
            datastore = new ShapefileDataStore(new File(shapPath).toURI().toURL());
            datastore.setCharset(Charset.forName("GBK"));
            String typeName = datastore.getTypeNames()[0];
            FeatureSource<SimpleFeatureType, SimpleFeature> source = null;
            source = (FeatureSource<SimpleFeatureType, SimpleFeature>) datastore
                    .getFeatureSource(typeName);
            FeatureCollection<SimpleFeatureType, SimpleFeature> features = source
                    .getFeatures();

            File outfile = new File(jsonPath);
            OutputStream output = new FileOutputStream(outfile);
            StringWriter strWriter = new StringWriter();

            fjson.writeFeatureCollection(features, strWriter);
            String feaJsonString = strWriter.toString();
            System.out.println(feaJsonString);

            fjson.writeFeatureCollection(features, output);

            strWriter.flush();
            strWriter.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            datastore.dispose();
        }
    }

    public static String shp2GeoJsonStr1(String shpPath) throws IOException {
        String geoJson = "";
        ShapefileDataStore datastore = null;
        FeatureJSON fjson = new FeatureJSON();
        StringWriter strWriter = new StringWriter();

        try {
            datastore = new ShapefileDataStore(new File(shpPath).toURI().toURL());
            datastore.setCharset(Charset.forName("GBK"));
            String typeName = datastore.getTypeNames()[0];
            FeatureSource<SimpleFeatureType, SimpleFeature> source = null;
            source = (FeatureSource<SimpleFeatureType, SimpleFeature>) datastore
                    .getFeatureSource(typeName);
            FeatureCollection<SimpleFeatureType, SimpleFeature> features = source
                    .getFeatures();

            fjson.writeFeatureCollection(features, strWriter);
            geoJson = strWriter.toString();

            strWriter.flush();
            strWriter.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            datastore.dispose();
        }


        return geoJson;
    }

    public static void shp2GeoJson2(String shpPath) {

        ShapefileDataStore shpDataStore = null;
        FeatureJSON fjson = new FeatureJSON();
        File file = new File(shpPath);

        try {
            URL url = file.toURI().toURL();
            shpDataStore = new ShapefileDataStore(url);
            shpDataStore.setCharset(Charset.forName("GBK"));
            String typeName = shpDataStore.getTypeNames()[0];

            // 遍历所有要素
            // land
            SimpleFeatureSource featureSource = shpDataStore
                    .getFeatureSource(typeName);
            SimpleFeatureCollection feaCollections = featureSource
                    .getFeatures();

            SimpleFeatureIterator feaIter = feaCollections.features();
            while (feaIter.hasNext()) {
                // block
                SimpleFeature feature = feaIter.next();
                // 获取Feature相关信息
                StringWriter strWriter = new StringWriter();
                fjson.writeFeature(feature, strWriter);
                String feaJsonString = strWriter.toString();
                // System.out.println(feaJsonString);

                JSONObject feaObject = JSON.parseObject(feaJsonString);
                String feaId = feaObject.getString("id");
                String feaType = feaObject.getString("type");

                JSONObject feaProperties = feaObject.getJSONObject("properties");
                for (Map.Entry<String, Object> entry : feaProperties.entrySet()) {
                    String fieldName = entry.getKey();
                    String fieldValue = entry.getValue().toString();

                    System.out.println(fieldName + ":" + fieldValue);
                }

                // 获取Geometry相关信息
                JSONObject geoObject = feaObject.getJSONObject("geometry");
                String feaGeoType = geoObject.getString("type");

                // geometry坐标串
                JSONArray feaGeoCoords = geoObject.getJSONArray("coordinates");
                for (int i = 0; i < feaGeoCoords.size(); i++) {
                    JSONArray coords01 = feaGeoCoords.getJSONArray(i);
                    System.out.println("1----->" + coords01);
                    for (int j = 0; j < coords01.size(); j++) {
                        // ring
                        JSONArray coords001 = coords01.getJSONArray(j);
                        System.out.println("2----->" + coords001);
                        for (int k = 0; k < coords001.size(); k++) {
                            // point
                            JSONArray coords0001 = coords001.getJSONArray(k);
                            System.out.println("3----->" + coords0001);

                        }
                    }
                }
            }
            feaIter.close();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            shpDataStore.dispose();
        }
    }

    public static void shp2GeoJson3(String shpPath) {
        ShapefileDataStore shpDataStore = null;
        FeatureJSON fjson = new FeatureJSON();
        File file = new File(shpPath);

        try {
            URL url = file.toURI().toURL();
            shpDataStore = new ShapefileDataStore(url);
            shpDataStore.setCharset(Charset.forName("GBK"));
            String typeName = shpDataStore.getTypeNames()[0];

            // 遍历所有要素
            // land
            SimpleFeatureSource featureSource = shpDataStore
                    .getFeatureSource(typeName);
            SimpleFeatureCollection feaCollections = featureSource
                    .getFeatures();

            // 获取Feature相关信息
            StringWriter strWriter = new StringWriter();
            fjson.writeFeatureCollection(feaCollections, strWriter);
            String feaJsonString = strWriter.toString();
            System.out.println(feaJsonString);

            //shp文件，里面包含了n个feature
            JSONObject shpObject = JSON.parseObject(feaJsonString);
            String shpType = shpObject.getString("type");
            String shpCrs = shpObject.getString("crs");

            JSONArray featuresArray = shpObject.getJSONArray("features");
            for (int n = 0; n < featuresArray.size(); n++) {
                //block
                //获取一个feature
                JSONObject featureObject = featuresArray.getJSONObject(n);

                //1、feature属性
                JSONObject feaProperties = featureObject.getJSONObject("properties");
                for (Map.Entry<String, Object> entry : feaProperties.entrySet()) {
                    String fieldName = entry.getKey();
                    String fieldValue = entry.getValue().toString();
                    System.out.println(fieldName + ":" + fieldValue);
                }

                //2、获取Geometry相关信息
                JSONObject geoObject = featureObject.getJSONObject("geometry");
                String feaGeoType = geoObject.getString("type");

                //3、geometry坐标串
                JSONArray feaGeoCoords = geoObject.getJSONArray("coordinates");
                for (int i = 0; i < feaGeoCoords.size(); i++) {
                    JSONArray jsonRings = feaGeoCoords.getJSONArray(i);
                    System.out.println("1----->" + jsonRings);
                    for (int j = 0; j < jsonRings.size(); j++) {
                        //ring
                        JSONArray jsonRing = jsonRings.getJSONArray(j);
                        System.out.println("2----->" + jsonRing);
                        for (int k = 0; k < jsonRing.size(); k++) {
                            // point
                            JSONArray jsonCoords = jsonRing.getJSONArray(k);
                            System.out.println("3----->" + jsonCoords);
                        }
                        System.out.println("-----------------------");
                    }
                }
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            shpDataStore.dispose();
        }
    }

}